import 'dart:async';

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:my_photos/core/configuration.dart';
import 'package:my_photos/core/network/network.dart';
import 'package:my_photos/generated/l10n.dart';
import 'package:my_photos/logging.dart';
import 'package:my_photos/ui/account/ott_verification_page.dart';
import 'package:my_photos/ui/account/password_entry_page.dart';
import 'package:my_photos/utils/dialog_util.dart';
// import 'package:shared_preferences/shared_preferences.dart';

class UserService {
  UserService._privateConstructor();

  static final UserService instance = UserService._privateConstructor();

  final _dio = NetworkClient.instance.getDio();
  final _config = Configuration.instance;
  // late SharedPreferences _preferences;

  Future<void> init() async {
    // _preferences = await SharedPreferences.getInstance();
  }

  Future<void> sendOtt(
    BuildContext context,
    String email, {
    bool isChangeEmail = false,
    bool isCreateAccountScreen = false,
  }) async {
    try {
      Logging.instance.$("send post");
      final response = await _dio.post(
        _config.getHttpEndpoint() + "/users/ott",
        data: {
          "email": email,
          "purpose": isChangeEmail ? "change" : "",
        },
      );
      if (response.statusCode == 200) {
        Logging.instance.$("success");
        unawaited(
          Navigator.of(context).push(
            MaterialPageRoute(
              builder: (BuildContext context) {
                return OTTVerificationPage(
                  email,
                  isChangeEmail: isChangeEmail,
                  isCreateAccountScreen: isCreateAccountScreen,
                );
              },
            ),
          ),
        );
      }
    } on DioError catch (e) {
      Logging.instance.$("error - dioerror");
    } catch (e) {
      Logging.instance.$("error");
    }
  }

  Future<void> changeEmail(
    BuildContext context,
    String email,
    String ott,
  ) async {}

  Future<void> verifyEmail(BuildContext context, String ott) async {
    final dialog = createProgressDialog(context, S.of(context).pleaseWait);
    await dialog.show();
    try {
      final response = await _dio.post(
        _config.getHttpEndpoint() + "users/verify-email",
        data: {
          "email": _config.getEmail(),
          "ott": ott,
        },
      );
      await dialog.hide();
      if (response.statusCode == 200) {
        Widget page = const PasswordEntryPage();
        // final String twoFASessionID = response.data["twoFactorSessionID"];
        // if (twoFASessionID.isNotEmpty) {
        //   setTwoFactor(value: true);
        //   page = TwoFactorAuthenticationPage(twoFASessionID);
        // } else {
        //   await _saveConfiguration(response);
        //   if (Configuration.instance.getEncryptedToken() != null) {
        //     page = const PasswordReentryPage();
        //   } else {
        //     page = const PasswordEntryPage();
        //   }
        // }
        Navigator.of(context).pushAndRemoveUntil(
          MaterialPageRoute(
            builder: (BuildContext context) {
              return page;
            },
          ),
          (route) => route.isFirst,
        );
      } else {
        // should never reach here
        throw Exception("unexpected response during email verification");
      }
    } on DioError catch (e) {
      Logging.instance.$(e);
      await dialog.hide();
      if (e.response != null && e.response!.statusCode == 410) {
        await showErrorDialog(
          context,
          S.of(context).oops,
          S.of(context).yourVerificationCodeHasExpired,
        );
        Navigator.of(context).pop();
      } else {
        showErrorDialog(
          context,
          S.of(context).incorrectCode,
          S.of(context).sorryTheCodeYouveEnteredIsIncorrect,
        );
      }
    } catch (e) {
      await dialog.hide();
      // _logger.severe(e);
      showErrorDialog(
        context,
        S.of(context).oops,
        S.of(context).verificationFailedPleaseTryAgain,
      );
    }
  }
}
